package com.guohui.boot1.controller;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * 自定义error页面处理，用于处理请求未进入Controller逻辑时抛出异常，由Spring boot重定向到/error页面的场景
 * @author GUOHUI
 * @version V1.0
 * @date 2017年8月8日 下午1:17:59
 */
@Controller
public class MyErrorController implements ErrorController {

  /**
   * spring boot的默认错误页面地址,必须是/error 否则无法找到
   */
  private final static String ERROR_PATH = "/error";

  /**
   * Error Attributes in the Application
   */
  @Autowired
  private ErrorAttributes errorAttributes;

  @GetMapping(value=ERROR_PATH)
  @ResponseBody
  public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
    Map<String, Object> body = getErrorAttributes(request, getTraceParameter(request));
    HttpStatus status = getStatus(request);
    return new ResponseEntity<Map<String, Object>>(body, status);
  }

  private HttpStatus getStatus(HttpServletRequest request) {
    Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
    if (statusCode != null) {
      try {
        return HttpStatus.valueOf(statusCode);
      } catch (Exception ex) {
      }
    }
    return HttpStatus.INTERNAL_SERVER_ERROR;
  }

  private Map<String, Object> getErrorAttributes(HttpServletRequest request,
      boolean includeStackTrace) {
    RequestAttributes requestAttributes = new ServletRequestAttributes(request);
    Map<String, Object> map =
        this.errorAttributes.getErrorAttributes(requestAttributes, includeStackTrace);
    map.put("out controller exception:", "控制器外异常处理");
    return map;
  }

  private boolean getTraceParameter(HttpServletRequest request) {
    String parameter = request.getParameter("trace");
    if (parameter == null) {
      return false;
    }
    return !"false".equals(parameter.toLowerCase());
  }

  /**
   * @Method: getErrorPath
   * @return
   * @see org.springframework.boot.autoconfigure.web.ErrorController#getErrorPath()
   */
  @Override
  public String getErrorPath() {
    return ERROR_PATH;
  }

}
